package com.partsoft.spring.support;

import java.io.File;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import com.partsoft.dits.dsm.DefaultContextDataSourceMonitorManager;
import com.partsoft.dits.dsm.DsmOriginalSQLs;
import com.partsoft.dits.integrate.ContextTableBroadcastDescriptorManager;
import com.partsoft.spring.log.Log;
import com.partsoft.utils.Assert;

public class DataSourceMonitorBeanDefinitionParaser implements BeanDefinitionParser {

	public static final String ElementName = "datasource-monitor";

	public static final String DefaultDataSourceMonitorManagerID = "dataSourceMonitor";

	public static final String TableBroadcastIdSuffix = "Registry";

	public BeanDefinition parse(Element element, ParserContext parserContext) {
		Assert.notNull(element);
		Assert.notNull(parserContext);
		String template_dir = element.hasAttribute("templatedir") ? element.getAttribute("templatedir") : null;
		Assert.hasText(template_dir, String.format("Must be set templatedir property for <%s> node", ElementName));

		String dsmId = element.hasAttribute("id") ? element.getAttribute("id") : DefaultDataSourceMonitorManagerID;
		String tableBDRId = dsmId + TableBroadcastIdSuffix;
		String config_location = element.hasAttribute("config") ? element.getAttribute("config") : template_dir
				+ File.separator + dsmId + ".xml";
		String tableBDR_config = null;
		if (config_location.toLowerCase().endsWith(".xml")) {
			tableBDR_config = config_location.substring(0, config_location.length() - 4) + ".data.xml";
		} else {
			tableBDR_config = config_location + ".data.xml";
		}

		String config_readonly = element.hasAttribute("readonly") ? element.getAttribute("readonly") : "false";
		String logtable_name = element.hasAttribute("logtable") ? element.getAttribute("logtable")
				: DsmOriginalSQLs.Constants.MonitorLogTable;

		String dsfactory = element.hasAttribute("factory") ? element.getAttribute("factory")
				: DataSourceFactoryBeanDefinitionParaser.DefaultDataSourceFactoryID;

		BeanDefinitionBuilder tableBDRBuilder = BeanDefinitionBuilder
				.rootBeanDefinition(ContextTableBroadcastDescriptorManager.class);
		tableBDRBuilder.addPropertyReference("dataSourceFactory", dsfactory);
		tableBDRBuilder.addPropertyValue("contextProfileLocation", tableBDR_config);
		tableBDRBuilder.addPropertyValue("transformScriptDirectoryLocation", template_dir);
		tableBDRBuilder.addPropertyValue("profileCanBeWrite", !"true".equalsIgnoreCase(config_readonly));
		tableBDRBuilder.addPropertyValue("createProfileNoExists", !"true".equalsIgnoreCase(config_readonly) && true);
		parserContext.getRegistry().registerBeanDefinition(tableBDRId, tableBDRBuilder.getBeanDefinition());

		BeanDefinitionBuilder dsmBuilder = BeanDefinitionBuilder
				.rootBeanDefinition(DefaultContextDataSourceMonitorManager.class);
		dsmBuilder.addPropertyValue("contextProfileLocation", config_location);
		dsmBuilder.addPropertyValue("profileCanBeWrite", !"true".equalsIgnoreCase(config_readonly));
		dsmBuilder.addPropertyValue("createProfileNoExists", !"true".equalsIgnoreCase(config_readonly) && true);
		dsmBuilder.addPropertyValue("monitorLogTable", logtable_name);
		dsmBuilder.addPropertyReference("dataSourceFactory", dsfactory);
		dsmBuilder.addPropertyReference("dataDescriptorRegistry", tableBDRId);
		parserContext.getRegistry().registerBeanDefinition(dsmId, dsmBuilder.getBeanDefinition());
		if (Log.isDebugEnabled()) {
			Log.debug(dsmBuilder.toString());
		}
		return null;
	}
}
